498C - Array and Operations - CodeForces Solution


flows graph matchings number theory *2100

Please click on ads to support us..

C++ Code:

#include<bits/stdc++.h>
using namespace std;

#ifdef local
#include"debug/debug.cpp"
#else
#define dbg(...)
#endif


#define test_case int test_cases;\
    cin>>test_cases;\
    for(i = 1; i<=test_cases;++i)

#define lu(i,l, r) for(int i = l; i < r; ++i)
#define ld(i, r, l) for(int i = r; i >= l; --i)
#define in_c(A, l, r) for(int input_iter = l; input_iter < r; ++input_iter) cin >> A[input_iter]

#define Max_heap priority_queue<int>
#define Min_heap priority_queue<int, vector<int>, greater<int>>

#define precision cout<<std::fixed<<setprecision(25);\
    cerr<<std::fixed<<setprecision(25)
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define all(A) (A).begin(),(A).end()
#define kick "Case #"<<test<<": "
#define endl "\n"
typedef long long ll;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

int mod = 1e9 + 7;

ll ceil(ll a, ll b) {
    return (a + b - 1) / b;
}

vector<int> d4x{0, 0, 1, -1};
vector<int> d4y{ -1, 1, 0, 0};
vector<int> d8x{0 , 0, 1, -1, 1, 1, -1, -1};
vector<int> d8y{1, -1, 0, 0, -1, 1, 1, -1};

class EdmondsKarp {
	static const int N = 1000; // max number of nodes

	int residual[N][N];

	vector<int> graph[N];

public:

	void reset() {
		memset(residual, 0, N * N);
	}

	EdmondsKarp() {
		reset();
	}

	EdmondsKarp(vector<pair<int,int>> graph[], int n) {
		reset();

		lu(i, 0, n) {
			addEdges(i, graph[i]);
		}
	}

	EdmondsKarp(vector<vector<pair<int,int>>> &graph) {
		reset();

		lu(i, 0, graph.size()) {
			addEdges(i, graph[i]);
		}
	}

	void addEdge(int s, int d, int c) {
		graph[s].push_back(d);
		residual[s][d] = c;
        residual[d][s] = 0;
		graph[d].push_back(s);
	}

	void addEdges(int s, vector<pair<int,int>> &ds) {
		for(pair<int,int> &iter : ds) {
			addEdge(s, iter.first, iter.second);
		}
	}

	int getFlow(int s, int t, vector<int> &parent) {

		fill(all(parent), -1);

		parent[s] = -2;


		queue<pair<int,int>> q;

		q.push({s, INT_MAX});

		while(!q.empty()) {
			pair<int,int> nodePair = q.front();
			q.pop();

			int node = nodePair.first; 
			int currentFlow = nodePair.second;

			if(node == t) {
				return currentFlow;
			}

			for(int neighbour : graph[node]) {
				if(parent[neighbour] == -1 && residual[node][neighbour] > 0) {
					parent[neighbour] = node;
					q.push({neighbour, min(currentFlow, residual[node][neighbour])});
				}
			}
		}

		return 0;
	}

	ll getMaxFlow(int s, int t) {
		vector<int> parent(N, -1);

		ll flow = 0;
		int currentFlow;

		while(currentFlow = getFlow(s, t, parent)) {
            dbg("flow", currentFlow);
			flow += currentFlow;

			int parNode = parent[t];
			int currNode = t;

			while(parNode != -2) {
                dbg(parNode);
				residual[parNode][currNode] -= currentFlow;

				residual[currNode][parNode] += currentFlow;

				currNode = parNode;
				parNode = parent[parNode];
			}
		}

		return flow;
	}
};

vector<pair<int,int>> getPrimes(int n) {
    vector<pair<int,int>> ans;

    int i = 2;

    for(i = 2; i*1ll* i <= n; ++i) {
        int cnt = 0;

        while(n%i == 0) {
            cnt++;
            n/=i;
        }

        if(cnt) {
            ans.push_back({i, cnt});
        }
    }

    if(n != 1) {
        ans.push_back({n, 1});
    }
    return ans;
}

void solve(int test) {
    int n, m;
    cin>>n>>m;
    vector<int> A(n);
    in_c(A, 0, n);

    EdmondsKarp maxFlow;

    map<int,map<int,pair<int,int>>> nodes;

    int start = 999, end = 998;
    int index =1;

    lu(i, 0, n) {
        vector<pair<int,int>> primes = getPrimes(A[i]);

        for(auto iter : primes) {
            nodes[i][iter.first] = {
                index++, iter.second
            };
        }
    }

    vector<bool> added(n, false);

    lu(i, 0, m) {
        int x, y;
        cin>>x>>y;
        --x;--y;
        if(x&1) {
            swap(x, y);
        }
        if(!added[x]) {
            added[x] = true;
          
            for(auto iter : nodes[x]) {
                maxFlow.addEdge(start, iter.second.first, iter.second.second);
                // dbg(start, iter.second.first);
            }
        }

        if(!added[y]) {
            added[y] = true;
            for(auto iter : nodes[y]) {
                maxFlow.addEdge(iter.second.first, end, iter.second.second);
                // dbg(iter.second.first, end);
            }
        }

        for(auto iter: nodes[x]) {
            maxFlow.addEdge(iter.second.first, nodes[y][iter.first].first, 34);
            // dbg(iter.second.first, nodes[y][iter.first].first);
        }
    }

    cout<<maxFlow.getMaxFlow(start, end);
}

int main() {
    precision;
    fastio;
    int i = 1;
    // test_case
    solve(i);
    return 0;
}


Comments

Submit
0 Comments
More Questions

1475A - Odd Divisor
1454B - Unique Bid Auction
978C - Letters
501B - Misha and Changing Handles
1496A - Split it
1666L - Labyrinth
1294B - Collecting Packages
1642B - Power Walking
1424M - Ancient Language
600C - Make Palindrome
1669D - Colorful Stamp
1669B - Triple
1669A - Division
1669H - Maximal AND
1669E - 2-Letter Strings
483A - Counterexample
3C - Tic-tac-toe
1669F - Eating Candies
1323B - Count Subrectangles
991C - Candies
1463A - Dungeon
1671D - Insert a Progression
1671A - String Building
1671B - Consecutive Points Segment
1671C - Dolce Vita
1669G - Fall Down
4D - Mysterious Present
1316B - String Modification
1204A - BowWow and the Timetable
508B - Anton and currency you all know